#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>

enum spectrum {red, orange, yellow, green, blue, violet, end};
const char * colors[] = {"red", "orange", "yellow", "green", "blue", "violet"};

typedef char * (* CALL_FP_CHARP)(char *);

#define LEN 81

char menu(void);
void eatline(void);
char * s_gets(char * , int);

char * to_upper(char *);
char * to_lower(char *);
char * transpose(char *);
char * dummy(char *);

void show(CALL_FP_CHARP, char * str);

int main(void)
{
    char line[LEN];
    char copy[LEN];

    char choice;
    CALL_FP_CHARP pt;

    puts("Enter a string (empty line to quit) :");
    while (s_gets(line, LEN) && line[0] != 0) {
        while ((choice = menu()) != 'n')
        {
            switch (choice) {
                case 'u':
                    pt = to_upper; break;

                case 'l':
                    pt = to_lower; break;

                case 't':
                    pt = transpose; break;

                case 'o':
                    pt = dummy; break;
            }
            strcpy(copy, line);
            show(pt, copy);
        }
        putchar('\n');

    }

    return 0;
}

char menu(void)
{
    char ret;
    puts("Enter menu choice:");
    puts("u) uppercase      l) lowercase");
    puts("t) transposed     o) original case");
    puts("n) next string");

    do {
        puts("Please enter a [u], [l], [t], [o] or [n] :");
        ret = getchar();
        eatline();
    } while (strchr("ulton", ret) == NULL);
    return tolower(ret);
}

char * to_lower(char * str)
{
    int i = 0;
    while (( *(str+i) = tolower(*(str+i)) ))
        ++i;
    return str;
}

char * to_upper(char * str)
{
    int i = 0;
    while (( *(str+i) = toupper(*(str+i)) ))
        ++i;
    return str;
}

char * transpose(char * str)
{
    char * ch = str;
    while (*str) {
        *str = isupper(*str)? tolower(*str): toupper(*str);
        ++str;
    }
    return ch;

}

char * dummy(char * str)
{
    return str;
}

void show(CALL_FP_CHARP fp, char * str)
{
    (*fp)(str);
    puts(str);

}

void eatline(void)
{
    while (getchar() != '\n')
        ;
}

char * s_gets(char * pt, int n)
{
    char * ret_val;
    char * find;

    if ((ret_val = fgets(pt, n, stdin)) != NULL) {
        find = strchr(pt, '\n');
        if (find)
            *find = 0;
        else
            while (getchar() != '\n')
                ;
    }

    return ret_val;
}


